#include "NetworkThread.h"
#include "ViewerProtocolFactory.h"
#include "ViewerProtocol.h"
#include "config.h"
#include <iostream>

using namespace std;

void error(const char *msg)
{
	perror(msg);
	exit(0);
}

void PrintMatrixSexy(float *m)
{
	puts("Printing Matrix in a sexy way!\n");
	for (int i = 0; i < 4; ++i)
	{
		printf("|");
		for (int j = 0; j < 4; ++j)
		{
			printf("%2.2f ", m[i * 4 + j]);
		}
		printf("|\n");
	}
	printf("\n");
}

NetworkThread::NetworkThread(QString i)
{
	serverIP = i;
}

void NetworkThread::run()
{
	frameRate = 30;
	float *m;

	ViewerProtocol *protocol = ViewerProtocolFactory::create("SdlSocketTcp");
	try
	{
		protocol->connect(serverIP);
	} catch (NetworkException E)
	{
		cout << E.showReason().toStdString() << endl;
		emit networkErrorSign(E.showReason());
		return;
	}
	int sleepTime = 1000000 / frameRate;
	while (1)
	{
		try
		{
			protocol->sendRequest();

			int x;

			//ADD_ELEMENTS:
			x = protocol->receive();
			if (protocol->getCount() > 0)
			{
				//				puts("Should add objects!");
				for (int i = 0; i < protocol->getCount(); ++i)
				{
					//				puts("Should and object!");
					ElementData *e =
							new ElementData(protocol->getNewElement(i));

					printf("New element: %d , ", e->getElementType());
					if (e->getElementType() != 8)
					{
						printf("DC: %d  \n", e->getDataCount());
					} else {
						printf("Mesh: %s \n", e->getMeshType());
					}
					emit addElementSign(e);
				}
			}
			//DELETE_ELEMENTS
			x = protocol->receive();
			if (protocol->getCount() > 0)
			{
				puts("Should delete objects!");
			}

			//CHANGE_ELEMENTS:
			x = protocol->receive();
			if (protocol->getCount() > 0)
			{
				//puts("getLocations:");
				char* bla = new char[30];
				time_t timestamp = time(NULL);
				strftime(bla, 30, "%H:%M:%S: ", localtime(&timestamp));
				//puts(bla);
				m = protocol->getLocationData();
				int c = protocol->getCount();
				//				printf("%d\n", c);
				//							for (int i = 0; i < c; ++i)
				//							{
				//								PrintMatrixSexy(m + i * 16 * 4);
				//							}
				emit changeElementSign(m);

                                //printf("getLocations done\n");
			}
		} catch (NetworkException E)
		{
			cout << E.showReason().toStdString() << endl;
			emit networkErrorSign(E.showReason());
			return;
		}
		usleep(sleepTime);
	}
}
